class OverrideFinally {
  constructor() {
    this.finallyFunc = null;
  }

  setFinallyFunc(func) {
    this.finallyFunc = func;
  }

  callFinally() {
    if (this.finallyFunc) {
      this.finallyFunc();
      this.finallyFunc = null;
      return true;
    }
    else {
      return false;
    }
  }
}
let overrideFinally = new OverrideFinally();

/* 演出 */
//单句对话
const DIALOGUE_TYPE = {
  narrator: "Narrator",
  imgNarrator: "imgNarrator",
  lines: "lines",
};
class Dialogue {
    constructor(content, heroine, img) {
        this.content = content ?? "";
        //如果heroine为null，则不是人物台词，是居中显示的旁白
        this.heroine = heroine;
        if (heroine != null) {
          this.avatar = heroine.avatar;
        }
        //如果img不为null，不是文字旁白也不是人物台词，是图片旁白（对话列表居中显示一张图片）
        this.img = img;
    }

    getType() {
        if(this.img != null)
        {
            return DIALOGUE_TYPE.imgNarrator;
        }
        else if(this.heroine == null)
        {
            return DIALOGUE_TYPE.narrator;
        }
        else
        {
            return DIALOGUE_TYPE.lines;
        }
    }
}

function newNarratorDialogue(content) {
  return new Dialogue(content);
}

function newImgNarratorDialogue(img, content) {
  return new Dialogue(content, null, img);
}

function newLinesDialogue(content, heroine) {
  return new Dialogue(content, heroine);
}

//整场演出
class Show {
  constructor(dialogueList = []) { 
    this.dialogueList = dialogueList; 
  }
      
  add(dialogueObj) { 
    this.dialogueList.push(dialogueObj); 
  }
}

/* 阶段 */
//每个slot中有多个event，根据不同情况会触发不同event
class Event {
  constructor(inUnlockFunc, inDecisionFunc, inYesEventBody, inNoEventBody) {
    this.unlockFunc = inUnlockFunc;
    this.decisionFunc = inDecisionFunc;
    this.yesEventBody = inYesEventBody;
    this.noEventBody = inNoEventBody;
  }

  isUnlock() {
    return this.unlockFunc();
  }

  async do() {
    if(this.decisionFunc()) {
      await this.yesEventBody();
    }
    else {
      await this.noEventBody();
    }
  }
}

//每个阶段中有多个slot，玩家可以选择（lock的slot不能选择）
class Slot {
  constructor(describe, eventList = []) {
    this.describe = describe;
    this.eventList = eventList;
    this.finallyCallback = () => {};
  }

  addEvent(eventObj) {
    this.eventList.push(eventObj);
  }

  isUnlock() {
    for(let eventObj of this.eventList) {
      if(eventObj.isUnlock()) {
        this.targetEventObj = eventObj;
        return true;
      }
    }
    return false;
  }

  async trigger() {
    window.aegis.reportEvent({
				name : 'SlotTrigger',
				ext1 : `${this.describe}`, 
		});
    await this.targetEventObj.do();

    if(!overrideFinally.callFinally()) { //调override的finally
      this.finallyCallback(); //调slot的finally
    }
  }
}

class Stage {
  constructor(title, describe, img, finallyCallback, slotList = []) {
    this.title = title;
    this.describe = describe;
    this.img = img;
    this.finallyCallback = finallyCallback;
    this.slotList = slotList;
    for(let slot of this.slotList) {
      slot.finallyCallback = this.finallyCallback;
    }
  }

  addSlot(slotObj) {
    slotObj.finallyCallback = this.finallyCallback;
    this.slotList.push(slotObj);
  }
}

export { overrideFinally, Stage, Slot, Event, Show, Dialogue, DIALOGUE_TYPE, 
    newNarratorDialogue, newImgNarratorDialogue, newLinesDialogue }